#include "W25Q64_Storage.h"
#include "W25Q64.h"
#include <stdio.h>
#include <string.h>
#include "stm32f10x_iwdg.h"

/* 全局变量 */
static W25Q64_Storage_Info_TypeDef storage_info;
static uint8_t storage_initialized = 0;

/**
  * @brief  W25Q64存储系统初始化
  * @param  None
  * @retval W25Q64_Storage_Status_TypeDef 操作状态
  */
W25Q64_Storage_Status_TypeDef W25Q64_Storage_Init(void)
{
    uint8_t mid;
    uint16_t did;
    
    /* 初始化W25Q64硬件 */
    W25Q64_Init();
    
    /* 检测芯片ID */
    W25Q64_ReadID(&mid, &did);
    if(mid != 0xEF || did != 0x4017)  // W25Q64的ID
    {
        printf("W25Q64芯片检测失败! MID=0x%02X, DID=0x%04X\r\n", mid, did);
        return W25Q64_STORAGE_CHIP_ERROR;
    }
    
    printf("W25Q64芯片检测成功! MID=0x%02X, DID=0x%04X\r\n", mid, did);
    
    /* 读取存储管理信息 */
    W25Q64_ReadData(STORAGE_INFO_ADDR, (uint8_t*)&storage_info, sizeof(storage_info));
    
    /* 检查是否为首次使用 */
    if(storage_info.magic_number != 0x12345678)
    {
        printf("检测到首次使用，正在初始化存储区域...\r\n");
        
        /* 初始化存储管理信息 */
        memset(&storage_info, 0, sizeof(storage_info));
        storage_info.magic_number = 0x12345678;
        storage_info.total_records = 0;
        storage_info.current_sector = DHT11_DATA_START_SECTOR;
        storage_info.current_offset = 0;
        storage_info.oldest_record_addr = DHT11_DATA_START_ADDR;
        storage_info.newest_record_addr = DHT11_DATA_START_ADDR;
        storage_info.storage_mode = STORAGE_MODE_OVERWRITE;  // 默认覆盖模式
        
        /* 擦除存储信息扇区并写入初始信息 */
        W25Q64_SectorErase(STORAGE_INFO_ADDR);
        W25Q64_PageProgram(STORAGE_INFO_ADDR, (uint8_t*)&storage_info, sizeof(storage_info));
        
        printf("存储区域初始化完成\r\n");
    }
    else
    {
        printf("读取到存储管理信息，总记录数: %d\r\n", storage_info.total_records);
    }
    
    storage_initialized = 1;
    return W25Q64_STORAGE_SUCCESS;
}

/**
  * @brief  W25Q64存储系统测试 (简化版本)
  * @param  None
  * @retval W25Q64_Storage_Status_TypeDef 操作状态
  */
W25Q64_Storage_Status_TypeDef W25Q64_Storage_Test(void)
{
    // 简化测试：仅检查芯片是否已正确初始化
    if(!storage_initialized)
    {
        return W25Q64_STORAGE_ERROR;
    }
    
    // 芯片ID检测已在初始化时完成，直接返回成功
    return W25Q64_STORAGE_SUCCESS;
}

/**
  * @brief  格式化W25Q64存储区域
  * @param  None
  * @retval W25Q64_Storage_Status_TypeDef 操作状态
  */
W25Q64_Storage_Status_TypeDef W25Q64_Storage_Format(void)
{
    printf("开始格式化W25Q64存储区域...\r\n");
    
    /* 擦除所有DHT11数据扇区 */
    for(int i = 0; i < DHT11_DATA_SECTOR_COUNT; i++)
    {
        uint32_t sector_addr = (DHT11_DATA_START_SECTOR + i) * W25Q64_SECTOR_SIZE;
        W25Q64_SectorErase(sector_addr);
        printf("已擦除扇区 %d/%d\r\n", i+1, DHT11_DATA_SECTOR_COUNT);
    }
    
    /* 重新初始化存储管理信息 */
    memset(&storage_info, 0, sizeof(storage_info));
    storage_info.magic_number = 0x12345678;
    storage_info.total_records = 0;
    storage_info.current_sector = DHT11_DATA_START_SECTOR;
    storage_info.current_offset = 0;
    storage_info.oldest_record_addr = DHT11_DATA_START_ADDR;
    storage_info.newest_record_addr = DHT11_DATA_START_ADDR;
    storage_info.storage_mode = STORAGE_MODE_OVERWRITE;
    
    /* 擦除并更新存储信息 */
    W25Q64_SectorErase(STORAGE_INFO_ADDR);
    W25Q64_PageProgram(STORAGE_INFO_ADDR, (uint8_t*)&storage_info, sizeof(storage_info));
    
    printf("W25Q64存储区域格式化完成!\r\n");
    return W25Q64_STORAGE_SUCCESS;
}

/**
  * @brief  更新存储管理信息到Flash
  * @param  None
  * @retval W25Q64_Storage_Status_TypeDef 操作状态
  */
static W25Q64_Storage_Status_TypeDef Update_Storage_Info(void)
{
    /* 擦除存储信息扇区 */
    W25Q64_SectorErase(STORAGE_INFO_ADDR);
    
    /* 写入更新后的存储信息 */
    W25Q64_PageProgram(STORAGE_INFO_ADDR, (uint8_t*)&storage_info, sizeof(storage_info));
    
    return W25Q64_STORAGE_SUCCESS;
}

/**
  * @brief  保存DHT11数据到W25Q64
  * @param  dht11_data: DHT11数据指针
  * @param  timestamp: 时间戳
  * @retval W25Q64_Storage_Status_TypeDef 操作状态
  */
W25Q64_Storage_Status_TypeDef DHT11_W25Q64_SaveData(DHT11_Data_TypeDef *dht11_data, uint32_t timestamp)
{
    DHT11_W25Q64_Data_TypeDef w25q64_data;
    uint32_t write_addr;
    
    if(!storage_initialized)
    {
        return W25Q64_STORAGE_ERROR;
    }
    
    if(dht11_data == NULL)
    {
        return W25Q64_STORAGE_INVALID_PARAM;
    }
    
    /* 填充W25Q64数据结构 */
    w25q64_data.timestamp = timestamp;
    w25q64_data.humi_int = dht11_data->humi_int;
    w25q64_data.humi_deci = dht11_data->humi_deci;
    w25q64_data.temp_int = dht11_data->temp_int;
    w25q64_data.temp_deci = dht11_data->temp_deci;
    w25q64_data.check_sum = dht11_data->check_sum;
    w25q64_data.valid_flag = 0xAA;  // 标记为有效数据
    w25q64_data.reserved[0] = 0x00;
    w25q64_data.reserved[1] = 0x00;
    
    if(storage_info.storage_mode == STORAGE_MODE_OVERWRITE)
    {
        /* 覆盖模式：总是写入到起始地址 */
        write_addr = DHT11_DATA_START_ADDR;
        
        /* 如果不是第一次写入，先擦除扇区 */
        if(storage_info.total_records > 0)
        {
            W25Q64_SectorErase(DHT11_DATA_START_ADDR);
        }
        
        /* 写入数据 */
        W25Q64_PageProgram(write_addr, (uint8_t*)&w25q64_data, sizeof(w25q64_data));
        
        /* 更新存储信息 */
        storage_info.total_records = 1;  // 覆盖模式只保存一条记录
        storage_info.newest_record_addr = write_addr;
        storage_info.oldest_record_addr = write_addr;
    }
    else  // STORAGE_MODE_CIRCULAR
    {
        /* 环形缓冲模式 */
        write_addr = storage_info.current_sector * W25Q64_SECTOR_SIZE + storage_info.current_offset;
        
        /* 检查当前扇区是否有足够空间 */
        if(storage_info.current_offset + DHT11_RECORD_SIZE > W25Q64_SECTOR_SIZE)
        {
            /* 当前扇区空间不足，移动到下一个扇区 */
            storage_info.current_sector++;
            storage_info.current_offset = 0;
            
            /* 检查是否超出分配的扇区范围 */
            if(storage_info.current_sector >= DHT11_DATA_START_SECTOR + DHT11_DATA_SECTOR_COUNT)
            {
                /* 回到起始扇区，形成环形缓冲 */
                storage_info.current_sector = DHT11_DATA_START_SECTOR;
            }
            
            /* 擦除新扇区 */
            uint32_t sector_addr = storage_info.current_sector * W25Q64_SECTOR_SIZE;
            W25Q64_SectorErase(sector_addr);
            
            write_addr = sector_addr;
        }
        
        /* 写入数据 */
        W25Q64_PageProgram(write_addr, (uint8_t*)&w25q64_data, sizeof(w25q64_data));
        
        /* 更新存储信息 */
        storage_info.newest_record_addr = write_addr;
        storage_info.current_offset += DHT11_RECORD_SIZE;
        
        if(storage_info.total_records < MAX_DHT11_RECORDS)
        {
            storage_info.total_records++;
        }
        else
        {
            /* 缓冲区已满，更新最旧记录地址 */
            storage_info.oldest_record_addr = write_addr + DHT11_RECORD_SIZE;
            if(storage_info.oldest_record_addr >= DHT11_DATA_END_ADDR)
            {
                storage_info.oldest_record_addr = DHT11_DATA_START_ADDR;
            }
        }
    }
    
    /* 更新存储管理信息 */
    Update_Storage_Info();
    
    return W25Q64_STORAGE_SUCCESS;
}

/**
  * @brief  从W25Q64读取最新的DHT11数据
  * @param  data: 读取数据指针
  * @retval W25Q64_Storage_Status_TypeDef 操作状态
  */
W25Q64_Storage_Status_TypeDef DHT11_W25Q64_ReadLatestData(DHT11_W25Q64_Data_TypeDef *data)
{
    if(!storage_initialized || data == NULL)
    {
        return W25Q64_STORAGE_INVALID_PARAM;
    }
    
    if(storage_info.total_records == 0)
    {
        return W25Q64_STORAGE_EMPTY;
    }
    
    /* 从最新记录地址读取数据 */
    W25Q64_ReadData(storage_info.newest_record_addr, (uint8_t*)data, sizeof(DHT11_W25Q64_Data_TypeDef));
    
    /* 检查数据有效性 */
    if(data->valid_flag != 0xAA)
    {
        return W25Q64_STORAGE_ERROR;
    }
    
    return W25Q64_STORAGE_SUCCESS;
}

/**
  * @brief  根据索引读取DHT11数据
  * @param  index: 数据索引 (0为最新，1为次新，以此类推)
  * @param  data: 读取数据指针
  * @retval W25Q64_Storage_Status_TypeDef 操作状态
  */
W25Q64_Storage_Status_TypeDef DHT11_W25Q64_ReadDataByIndex(uint32_t index, DHT11_W25Q64_Data_TypeDef *data)
{
    uint32_t read_addr;
    
    if(!storage_initialized || data == NULL)
    {
        return W25Q64_STORAGE_INVALID_PARAM;
    }
    
    if(index >= storage_info.total_records)
    {
        return W25Q64_STORAGE_INVALID_PARAM;
    }
    
    if(storage_info.storage_mode == STORAGE_MODE_OVERWRITE)
    {
        /* 覆盖模式只有一条记录 */
        if(index > 0)
        {
            return W25Q64_STORAGE_INVALID_PARAM;
        }
        read_addr = DHT11_DATA_START_ADDR;
    }
    else
    {
        /* 环形缓冲模式：从最新记录向前计算地址 */
        read_addr = storage_info.newest_record_addr - (index * DHT11_RECORD_SIZE);
        
        /* 处理地址回绕 */
        if(read_addr < DHT11_DATA_START_ADDR)
        {
            read_addr += (DHT11_DATA_SECTOR_COUNT * W25Q64_SECTOR_SIZE);
        }
    }
    
    /* 读取数据 */
    W25Q64_ReadData(read_addr, (uint8_t*)data, sizeof(DHT11_W25Q64_Data_TypeDef));
    
    /* 检查数据有效性 */
    if(data->valid_flag != 0xAA)
    {
        return W25Q64_STORAGE_ERROR;
    }
    
    return W25Q64_STORAGE_SUCCESS;
}

/**
  * @brief  擦除所有DHT11数据
  * @param  None
  * @retval W25Q64_Storage_Status_TypeDef 操作状态
  */
W25Q64_Storage_Status_TypeDef DHT11_W25Q64_EraseAllData(void)
{
    return W25Q64_Storage_Format();
}

/**
  * @brief  设置存储模式
  * @param  mode: 存储模式
  * @retval W25Q64_Storage_Status_TypeDef 操作状态
  */
W25Q64_Storage_Status_TypeDef W25Q64_Storage_SetMode(Storage_Mode_TypeDef mode)
{
    if(!storage_initialized)
    {
        return W25Q64_STORAGE_ERROR;
    }
    
    storage_info.storage_mode = mode;
    Update_Storage_Info();
    
    printf("存储模式已设置为: %s\r\n", 
           (mode == STORAGE_MODE_OVERWRITE) ? "覆盖模式" : "环形缓冲模式");
    
    return W25Q64_STORAGE_SUCCESS;
}

/**
  * @brief  获取当前存储模式
  * @param  None
  * @retval Storage_Mode_TypeDef 存储模式
  */
Storage_Mode_TypeDef W25Q64_Storage_GetMode(void)
{
    return (Storage_Mode_TypeDef)storage_info.storage_mode;
}

/**
  * @brief  获取记录总数
  * @param  None
  * @retval uint32_t 记录总数
  */
uint32_t DHT11_W25Q64_GetRecordCount(void)
{
    return storage_info.total_records;
}

/**
  * @brief  检查是否有有效数据
  * @param  None
  * @retval uint8_t 1=有有效数据, 0=无有效数据
  */
uint8_t DHT11_W25Q64_HasValidData(void)
{
    return (storage_info.total_records > 0) ? 1 : 0;
}

/**
  * @brief  打印存储系统信息
  * @param  None
  * @retval None
  */
void W25Q64_Storage_PrintInfo(void)
{
    printf("\r\n=== W25Q64存储系统信息 ===\r\n");
    printf("魔数标识: 0x%08X\r\n", storage_info.magic_number);
    printf("总记录数: %d\r\n", storage_info.total_records);
    printf("存储模式: %s\r\n", 
           (storage_info.storage_mode == STORAGE_MODE_OVERWRITE) ? "覆盖模式" : "环形缓冲模式");
    printf("当前扇区: %d\r\n", storage_info.current_sector);
    printf("当前偏移: %d字节\r\n", storage_info.current_offset);
    printf("最新记录地址: 0x%08X\r\n", storage_info.newest_record_addr);
    printf("最旧记录地址: 0x%08X\r\n", storage_info.oldest_record_addr);
    printf("最大记录容量: %d条\r\n", MAX_DHT11_RECORDS);
    printf("单条记录大小: %d字节\r\n", DHT11_RECORD_SIZE);
    printf("分配存储空间: %dKB\r\n", (DHT11_DATA_SECTOR_COUNT * W25Q64_SECTOR_SIZE) / 1024);
    printf("========================\r\n");
}

/**
  * @brief  打印所有DHT11数据
  * @param  None
  * @retval None
  */
void DHT11_W25Q64_PrintAllData(void)
{
    DHT11_W25Q64_Data_TypeDef data;
    W25Q64_Storage_Status_TypeDef status;
    
    printf("\r\n=== W25Q64中的所有DHT11数据 ===\r\n");
    printf("总记录数: %d\r\n", storage_info.total_records);
    
    if(storage_info.total_records == 0)
    {
        printf("暂无数据记录\r\n");
        printf("=============================\r\n");
        return;
    }
    
    for(uint32_t i = 0; i < storage_info.total_records; i++)
    {
        status = DHT11_W25Q64_ReadDataByIndex(i, &data);
        if(status == W25Q64_STORAGE_SUCCESS)
        {
            printf("记录 %d: 时间戳=%ds, 温度=%d.%d℃, 湿度=%d.%d%%RH, 校验=0x%02X\r\n",
                   i, data.timestamp, data.temp_int, data.temp_deci, 
                   data.humi_int, data.humi_deci, data.check_sum);
        }
        else
        {
            printf("记录 %d: 读取失败 (错误码: %d)\r\n", i, status);
        }
    }
    printf("=============================\r\n");
}
